#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <functional>
#include "InetAddr.hpp"
#include "ThreadPool.hpp"

using task_t = std::function<void()>;

class MessageRoute{
private:
    // bool IsExist(InetAddr& user){
    //     auto iter = _online_user.find(user);
    //     if(iter == _online_user.end()) return false;
    //     return true;
    // }
    bool IsExist(const InetAddr &addr)
        {
            for (auto a : _online_user)
            {
                if (a == addr)
                    return true;
            }
            return false;
        }

public:
    MessageRoute(){

    }

    // void AddUser(InetAddr& user){
    //     if(IsExist(user)) return;
    //     _online_user.insert(user);
       
    // }

    // void DelUser(InetAddr& user){
    //     if(!IsExist(user)) return;
    //     _online_user.erase(user);
    // }

    void AddUser(const InetAddr &addr)
    {
        //LockGuard lockguard(&_mutex);
        if (IsExist(addr))
            return;
        _online_user.push_back(addr);
    }
    void DelUser(const InetAddr &addr)
    {
        //LockGuard lockguard(&_mutex);
        for (auto iter = _online_user.begin(); iter != _online_user.end(); iter++)
        {
            if (*iter == addr)
            {
                _online_user.erase(iter);
                break;
            }
        }
    }

    void RouteHelPer(int sockfd, const std::string message){
        for(auto iter : _online_user){
            struct sockaddr_in addr = iter.GetAddr();
            ::sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr*)&addr, socklen_t(sizeof(addr)));
        }
    }

    void Route(int sockfd, const std::string message, InetAddr user){
        AddUser(user);
        if(message == "quit"){
            DelUser(user);
        }
        //构建任务对象入队列，让线程池进行转发
        task_t t = std::bind(&MessageRoute::RouteHelPer, this, sockfd, message);
        ThreadPool<task_t>::GetInstance()->Enqueue(t);

    }   
    ~MessageRoute(){}
private:
    //std::set<InetAddr> _online_user;
    std::vector<InetAddr> _online_user;
};